package cfg

import (
	"log"

	"gpt-api/framework/db"

	"github.com/spf13/viper"
)

// NewMySQL create a new mysql instance from config file derived by micro-config
// whole config information is split into two files: one in config-map dir and one insecret dir
// # mysql-A.yaml in config-map dir
// mysql-A:
//
//	MaxOpenConn: 10
//	MaxIdleConn: 2
//
// # mysql.yaml in secret dir
// mysql-A:
//
//	  address: 127.0.0.1:3306
//		 host: user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8&parseTime=True&loc=Local
//
// params resourceName refers to "mysql-A" above
func NewMySQL(resourceName string, opt ...db.Option) *db.DB {
	address := viper.GetString(resourceName + ".address")
	if address == "" {
		log.Panic("load db configuration fail, mysql Address is empty")
		return nil
	}

	dbConfig := db.Config{
		Dialect:  db.MySQL,
		Username: viper.GetString(resourceName + ".username"),
		Password: viper.GetString(resourceName + ".password"),
		Address:  address,
		DBName:   viper.GetString(resourceName + ".dbname"),
	}

	if maxopen := viper.GetInt(resourceName + ".maxopenconn"); maxopen != 0 {
		opt = append(opt, db.WithMaxOpenConnections(maxopen))
	}

	if maxidle := viper.GetInt(resourceName + ".maxidleconn"); maxidle != 0 {
		opt = append(opt, db.WithMaxIdleConnections(maxidle))
	}

	if rtimeout := viper.GetString(resourceName + ".readtimeout"); rtimeout != "" {
		opt = append(opt, db.WithReadTimeout(rtimeout))
	}

	if wtimeout := viper.GetString(resourceName + ".writetimeout"); wtimeout != "" {
		opt = append(opt, db.WithWriteTimeout(wtimeout))
	}

	if logmod := viper.GetBool(resourceName + ".logmode"); logmod {
		opt = append(opt, db.WithLogMode(logmod))
	}

	dbEngine, err := db.New(dbConfig, opt...)
	if err != nil {
		log.Panicf("initial db fail %s", err)
	}

	return dbEngine
}

// NewPostgreSQL create a new potgresql instance from config file derived by micro-config
// whole config information is split into two files: one in config-map dir and one in secret dir
// # postgreql-A.yaml in config-map dir
// postgresql-A:
// till this moment, this file is empty
//
// # postgresql.yaml in secret dir
// postgresql-A:
//	 host: user:password@127.0.0.1:5432/dbname?sslmode=verify-full&connect_timeout=10
// params resourceName refers to "postgresql-A" above

func NewPostgreSQL(resourceName string, opt ...db.Option) *db.DB {
	address := viper.GetString(resourceName + ".address")
	if address == "" {
		log.Panic("load db configuration fail, postgresql Address is empty")
		return nil
	}

	dbConfig := db.Config{
		Dialect:    db.Postgres,
		Username:   viper.GetString(resourceName + ".username"),
		Password:   viper.GetString(resourceName + ".password"),
		Address:    address,
		DBName:     viper.GetString(resourceName + ".dbname"),
		SearchPath: "",
		Secondary:  viper.GetStringSlice(resourceName + ".secondary"),
	}

	if ssl := viper.GetString(resourceName + ".ssl"); ssl != "" {
		opt = append(opt, db.WithSslmode(ssl))
	}

	if logmod := viper.GetBool(resourceName + ".logmode"); logmod {
		opt = append(opt, db.WithLogMode(logmod))
	}

	dbEngine, err := db.New(dbConfig, opt...)

	if err != nil {
		log.Panicf("initial db fail %s", err)
	}
	return dbEngine
}
